// 高阶函数？
// 一个函数参数是函数， 或者一个函数返回一个函数， 外层的函数就是高阶函数

Array.prototype.reduce = function (fn, startVal) {
  // 参数是函数，可以和其他函数进行组合

  let acc = typeof startVal === "undefined" ? this[0] : startVal;
  let index = typeof startVal === "undefined" ? 1 : 0;
  for (let i = index; i < this.length; i++) {
    acc = fn(acc, this[i], i, this); // 抽象运算过程
  }
  return acc;
};

const total = [1, 2, 3, 4, 5, 6].reduce((memo, prev) => memo + prev, 0);
console.log(total);

// 函数作为返回值， 缓存，所谓的纯函数 输入一定输出一定 （来实现缓存）

// 什么是闭包？ 闭包不是固定的形式

// 闭包， 函数可以记住和访问当前所在的词法作用域 （声明决定） 函数是在当前词法作用域之外执行，就会产生闭包

function sum(a, b) {
  console.log("实际真实执行");
  return a + b;
}
function memoize(coreFn, resolver) {
  // 高阶函数  函数式编程， 纯函数
  const cache = new Map(); // 这个变量可以被 下面的函数访问
  return function (...args) {
    // 每次调用函数 重现创建一个缓存key ，用key来查找是否执行过
    let key = typeof resolver === "function" ? resolver(...args) : args[0];
    let r = cache.get(key);
    if (cache.has(r)) {
      r = coreFn(...args);
      cache.set(key, r); // 缓存结果
    }
    return r;
  };
}
const memorizedSum = memoize(sum, function (...args) {
  return JSON.stringify(args); // key 是根据需要自己创建的
});

console.log(memorizedSum(1, 2)); // 缓存  标识-》 结果  （vue3 keep-alive）
console.log(memorizedSum(1, 3));
console.log(memorizedSum(1, 2));

// 高阶函数的目的  组合（扩展） + 缓存
